package org.dromara.oce.service.remote.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bytedance.ads.ApiClient;
import com.bytedance.ads.api.*;
import com.bytedance.ads.model.EventManagerAssetsCreateV2RequestMiniProgramAsset;
import com.bytedance.ads.model.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.oce.config.JuLiangConfig;
import org.dromara.oce.config.JuLiangProperties;
import org.dromara.oce.constant.PlatformJuLangConstants;
import org.dromara.oce.constant.RedisKeyUtils;
import org.dromara.oce.domain.dto.ProjectPromotionAggregation;
import org.dromara.oce.domain.qo.*;
import org.dromara.oce.domain.req.*;
import org.dromara.oce.domain.vo.GetIesAccountSearchVo;
import org.dromara.oce.service.remote.OceanEngineRemoteService;
import org.dromara.oce.service.remote.OceanEngineThirdRemoteService;
import org.dromara.oce.utils.PlatformConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.Duration;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class OceanEngineThirdRemoteServiceImpl implements OceanEngineThirdRemoteService {

    private final JuLiangConfig juLiangConfig;
    private final OceanEngineRemoteService oceanEngineRemoteService;


    @Override
    public String getAccessToken(String account) {
        String key = RedisKeyUtils.getAccountAccessTokenKey(PlatformJuLangConstants.JULIANG, account);
        String accessToken = RedisUtils.getCacheObject(key);
        if (StringUtils.isNotBlank(accessToken)) {
            return accessToken;
        }
        return refreshToken(account);
    }

    @Override
    public String refreshToken(String account) {
        String appCode = juLiangConfig.getSystemParam("oce:app:appCode");
        appCode = appCode == null ? "jl_mytg" : appCode;
        String finalAppCode = appCode;
        JuLiangProperties juLiangProperties = juLiangConfig.getJuLiangConfigList().stream().filter(item -> item.getAppCode().equals(finalAppCode)).findFirst().get();

        String ref = RedisKeyUtils.getAccountRefreshTokenKey(PlatformConstants.JULIANG, account);
        String refresh_token = RedisUtils.getCacheObject(ref);
        if (StringUtils.isBlank(refresh_token)) {
            throw new ServiceException("请重新进行授权操作");
        }
        //获取新的accesstoken
        JSONObject json = new JSONObject();
        json.put("appid", juLiangProperties.getAppId());
        json.put("secret", juLiangProperties.getSecret());
        json.put("grant_type", "refresh_token");
        json.put("refresh_token", refresh_token);
        //发送post请求
        log.info("刷新Refresh Token接口请求参数：{}", JSONUtil.toJsonStr(json));
        String post = HttpUtil.post(juLiangConfig.getUrl() + "/open_api/oauth2/refresh_token/", JSONUtil.toJsonStr(json));
        log.info("刷新Refresh Token接口返回参数：{}", post);
        JSONObject resultObject = JSONObject.parseObject(post);
        int code = resultObject.getIntValue("code");
        String message = resultObject.getString("message");
        if (code != 0) {
            log.error("《巨量》刷新token失败，code={}, message={}", code, message);
            throw new ServiceException("《巨量》刷新token失败:" + message);
        }
        //获取data
        JSONObject data = resultObject.getJSONObject("data");
        if (data == null) {
            throw new ServiceException("《巨量》响应中未找到 'data' 字段");
        }
        String accessToken = data.getString("access_token");
        log.info("《巨量》accessToken:{}", accessToken);
        String refreshToken = data.getString("refresh_token");
        log.info("《巨量》refreshToken:{}", refreshToken);
        // token过期时间
        String key = RedisKeyUtils.getAccountAccessTokenKey(PlatformJuLangConstants.JULIANG, account);
        RedisUtils.setCacheObject(key, accessToken, Duration.ofSeconds(data.getLong("expires_in") - 200L));
        RedisUtils.setCacheObject(ref, refreshToken, Duration.ofSeconds(data.getLong("refresh_token_expires_in") - 200L));
        return accessToken;
    }


    @Override
    public List<Oauth2AdvertiserGetResponseDataListInner> getOauthAdvertiser(String appCode) {
        try {
            String accessToken = this.getAccessToken(appCode);

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            Oauth2AdvertiserGetApi api = new Oauth2AdvertiserGetApi();
            api.setApiClient(apiClient);

            List<Oauth2AdvertiserGetResponseDataListInner> list = null;

            Oauth2AdvertiserGetResponse response = api.openApiOauth2AdvertiserGetGet(accessToken);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            list = response.getData().getList();
            return list;
        } catch (Exception e) {
            throw new ServiceException("获取已授权账号失败," + e.getMessage());
        }
    }

    @Override
    public UserInfoV2ResponseData getOauthUserInfo(String account) {
        try {
            String accessToken = this.getAccessToken(account);

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            UserInfoV2Api api = new UserInfoV2Api();
            api.setApiClient(apiClient);

            UserInfoV2Response response = api.openApi2UserInfoGet();
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取已授权账号失败," + e.getMessage());
        }
    }

    @Override
    public CustomerCenterAdvertiserListV2ResponseData getCustomerCenterAdvertiserList(GetAccountAdvertiserlistQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            CustomerCenterAdvertiserListV2Api api = new CustomerCenterAdvertiserListV2Api();
            api.setApiClient(apiClient);

            CustomerCenterAdvertiserListV2Filtering filtering = new CustomerCenterAdvertiserListV2Filtering();
            filtering.setAccountName(qo.getAdvertiserName());

            CustomerCenterAdvertiserListV2Response response = api.openApi2CustomerCenterAdvertiserListGet(CustomerCenterAdvertiserListV2AccountSource.AD, qo.getAccountId(), filtering, qo.getPageNum(), qo.getPageSize());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取工作台下账号列表失败," + e.getMessage());
        }
    }

    @Override
    public List<AgentAdvertiserInfoQueryV2ResponseDataAccountDetailListInner> getAdvertiserInfo(Long accountId, List<Long> advertiserIds) {
        try {
            String accessToken = this.getAccessToken(accountId + "");
            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);


            AgentAdvertiserInfoQueryV2Api api = new AgentAdvertiserInfoQueryV2Api();
            api.setApiClient(apiClient);

            AgentAdvertiserInfoQueryV2Response response = api.openApi2AgentAdvertiserInfoQueryGet(advertiserIds);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getAccountDetailList();
        } catch (Exception e) {
            throw new ServiceException("获取工作台下账号列表失败," + e.getMessage());
        }
    }

    @Override
    public String uploadAdvertiserAvatar(Long advertiserId, File file) {
        try {
            String updateDateStr = juLiangConfig.getSystemParam("oce.update.advertserAvatar");

            String accessToken = oceanEngineRemoteService.getClientToken("jl_dsbb");
            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);


            AdvertiserAvatarUploadV2Api api = new AdvertiserAvatarUploadV2Api();
            api.setApiClient(apiClient);

            AdvertiserAvatarUploadV2Response response = api.openApi2AdvertiserAvatarUploadPost(advertiserId, file);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getImageId();
        } catch (Exception e) {
            throw new ServiceException("获取工作台下账号列表失败," + e.getMessage());
        }
    }

    @Override
    public Boolean updateAdvertiserAvatar(UpdateAdvertiserAvatarReq req) {
        try {
            String accessToken = oceanEngineRemoteService.getClientToken(req.getThirdAdvertiserAppCode());
            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            AdvertiserAvatarSubmitV2Api api = new AdvertiserAvatarSubmitV2Api();
            api.setApiClient(apiClient);

            AdvertiserAvatarSubmitV2Request request = new AdvertiserAvatarSubmitV2Request();
            BeanUtil.copyProperties(req, request);
            AdvertiserAvatarSubmitV2Response response = api.openApi2AdvertiserAvatarSubmitPost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            boolean isOk = response.getData().getAdvertiserId() != null;
            return true;
        } catch (Exception e) {
            throw new ServiceException("更新广告主账号头像失败," + e.getMessage());
        }
    }


    @Override
    public AdvertiserAvatarGetV2ResponseData queryAdvertiserAvatar(Long id, String appCode) {
        try {
            String accessToken = oceanEngineRemoteService.getClientToken(appCode);
            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            AdvertiserAvatarGetV2Api api = new AdvertiserAvatarGetV2Api();
            api.setApiClient(apiClient);

            AdvertiserAvatarGetV2Response response = api.openApi2AdvertiserAvatarGetGet(id);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("查询广告主账号头像失败," + e.getMessage());
        }
    }

    @Override
    public List<GetIesAccountSearchVo> getIesAccountSearch(GetIesAccountSearchQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");
            JSONObject param = new JSONObject();
            param.put("advertiser_id", qo.getAdvertiserId());

            String result = HttpRequest.get("https://ad.oceanengine.com/open_api/2/tools/ies_account_search/")
                .header("access-token", accessToken).form(param)
                .execute().body();

            JSONObject jsonObject = JSON.parseObject(result);
            int code = jsonObject.getInteger("code");
            if (code != 0) {
                throw new ServiceException(jsonObject.getString("message"));
            }
            String data = jsonObject.getString("data");

            List<GetIesAccountSearchVo> list = JSONArray.parseArray(data, GetIesAccountSearchVo.class);
            return list;
        } catch (Exception e) {
            throw new ServiceException("获取绑定的抖音号失败," + e.getMessage());
        }
    }

    @Override
    public BusinessPlatformCompanyInfoGetV30ResponseData getAccountAllCompanyInfo(GetAccountAllCompanyInfoQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);


            BusinessPlatformCompanyInfoGetV30Api api = new BusinessPlatformCompanyInfoGetV30Api();
            api.setApiClient(apiClient);

            BusinessPlatformCompanyInfoGetV30Response response = api.openApiV30BusinessPlatformCompanyInfoGetGet(qo.getAccountId(), qo.getPageNum().intValue(), qo.getPageSize().intValue());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取工作台下账号列表失败," + e.getMessage());
        }
    }

    @Override
    public List<DpaProductAvailablesV2ResponseDataListInner> getDptProductAvailablesList(Long accountId, Long advertiserId) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            DpaProductAvailablesV2Api api = new DpaProductAvailablesV2Api();
            api.setApiClient(apiClient);
            DpaProductAvailablesV2Response response = api.openApi2DpaProductAvailablesGet(advertiserId);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getList();
        } catch (Exception e) {
            throw new ServiceException("获取商品库信息失败," + e.getMessage());
        }
    }

    @Override
    public List<DpaDetailGetV2ResponseDataListInner> getDptProductList(GetDptProductListPageQo req) {
        try {
            String accessToken = this.getAccessToken(req.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            DpaDetailGetV2Api api = new DpaDetailGetV2Api();
            api.setApiClient(apiClient);

            DpaDetailGetV2Filtering filtering = new DpaDetailGetV2Filtering();
            filtering.setProductId(req.getProductId());
            filtering.setProductName(req.getProductName());
            filtering.setDpaCategories(req.getDpaCategories());
            DpaDetailGetV2Response response = api.openApi2DpaDetailGetGet(req.getAdvertiserId(), req.getProductPlatformId(), filtering, req.getPageNum().intValue(), req.getPageSize().intValue());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getList();
        } catch (Exception e) {
            throw new ServiceException("获取商品列表失败," + e.getMessage());
        }
    }

    @Override
    public DpaProductDetailGetV2ResponseData getProductDetail(GetProductDetailQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            DpaProductDetailGetV2Api api = new DpaProductDetailGetV2Api();
            api.setApiClient(apiClient);

            DpaProductDetailGetV2Filtering filtering = new DpaProductDetailGetV2Filtering();
            filtering.setProductIds(qo.getProductIds());
            DpaProductDetailGetV2Response response = api.openApi2DpaProductDetailGetGet(qo.getAdvertiserId(), filtering, qo.getPageNum(), qo.getPageSize(), qo.getPlatformId());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取商品详情失败," + e.getMessage());
        }
    }

    @Override
    public boolean createDptProduct(CreateDptProductReq req) {
        try {
            String accessToken = this.getAccessToken(req.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            DpaProductCreateV2Api api = new DpaProductCreateV2Api();
            api.setApiClient(apiClient);

            DpaProductCreateV2Request request = new DpaProductCreateV2Request();
            request.setAdvertiserId(req.getAdvertiserId());
            request.setPlatformId(req.getPlatformId());
            DpaProductCreateV2RequestProductInfo productInfo = new DpaProductCreateV2RequestProductInfo();
            request.setProductInfo(productInfo);

            BeanUtil.copyProperties(req.getProductInfo(), productInfo);
            DpaProductCreateV2Response response = api.openApi2DpaProductCreatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return true;
        } catch (Exception e) {
            throw new ServiceException("创建DPA商品失败," + e.getMessage());
        }
    }

    @Override
    public boolean updateBatchProductStatus(UpdateBatchProductStatusReq req) {
        try {
            String accessToken = this.getAccessToken(req.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            DpaProductStatusBatchUpdateV2Api api = new DpaProductStatusBatchUpdateV2Api();
            api.setApiClient(apiClient);

            DpaProductStatusBatchUpdateV2Request request = new DpaProductStatusBatchUpdateV2Request();
            BeanUtil.copyProperties(req, request);

            DpaProductStatusBatchUpdateV2Response response = api.openApi2DpaProductStatusBatchUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return true;
        } catch (Exception e) {
            throw new ServiceException("批量修改DPA商品状态失败," + e.getMessage());
        }
    }

    @Override
    public ToolsMicroAppCreateV30Response createToolsMicroApp(String accountId, CreateToolsMicroAppReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsMicroAppCreateV30Api api = new ToolsMicroAppCreateV30Api();
            api.setApiClient(apiClient);

            ToolsMicroAppCreateV30Request request = new ToolsMicroAppCreateV30Request();

            BeanUtil.copyProperties(req, request);
            request.setAppPage(BeanUtil.copyProperties(req.getAppPage(), ToolsMicroAppCreateV30RequestAppPage.class));
            ToolsMicroAppCreateV30Response response = api.openApiV30ToolsMicroAppCreatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response;
        } catch (Exception e) {
            throw new ServiceException("创建字节小程序失败," + e.getMessage());
        }
    }


    @Override
    public ToolsMicroAppUpdateV30Response updateToolsMicroApp(String accountId, UpdateToolsMicroAppReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsMicroAppUpdateV30Api api = new ToolsMicroAppUpdateV30Api();
            api.setApiClient(apiClient);

            ToolsMicroAppUpdateV30Request request = new ToolsMicroAppUpdateV30Request();
            BeanUtil.copyProperties(req, request);
            List<ToolsMicroAppUpdateV30RequestAppPageInner> appPage = BeanUtil.copyToList(req.getAppPage(), ToolsMicroAppUpdateV30RequestAppPageInner.class);
            request.setAppPage(appPage);
            ToolsMicroAppUpdateV30Response response = api.openApiV30ToolsMicroAppUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response;
        } catch (Exception e) {
            throw new ServiceException("更新字节小程序失败," + e.getMessage());
        }
    }

    @Override
    public ToolsMicroAppListV30ResponseData getToolsMicroAppList(GetToolsMicroAppListQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);
            ToolsMicroAppListV30Api api = new ToolsMicroAppListV30Api();
            api.setApiClient(apiClient);

            ToolsMicroAppListV30Filtering filtering = new ToolsMicroAppListV30Filtering();
            BeanUtil.copyProperties(qo, filtering);

            ToolsMicroAppListV30Response response = api.openApiV30ToolsMicroAppListGet(qo.getAdvertiserId(), filtering, qo.getPageNum().intValue(), qo.getPageSize().intValue());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取字节小程序失败," + e.getMessage());
        }
    }

    @Override
    public List<ToolsMicroAppListV30ResponseDataListInner> queryToolsMicroAppNew(GetToolsMicroAppListQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);
            ToolsMicroAppListV30Api api = new ToolsMicroAppListV30Api();
            api.setApiClient(apiClient);

            ToolsMicroAppListV30Filtering filtering = new ToolsMicroAppListV30Filtering();
            BeanUtil.copyProperties(qo, filtering);
            qo.setPageSize(100L);

            ToolsMicroAppListV30Response response = api.openApiV30ToolsMicroAppListGet(qo.getAdvertiserId(), filtering, qo.getPageNum().intValue(), qo.getPageSize().intValue());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            List<ToolsMicroAppListV30ResponseDataListInner> respList = new ArrayList<>();
            if (qo.getSearchType() == null) {
                ToolsMicroAppListV30Filtering filteringShare = new ToolsMicroAppListV30Filtering();
                BeanUtil.copyProperties(qo, filteringShare);
                filteringShare.setSearchType(ToolsMicroAppListV30FilteringSearchType.SHARE_ONLY);
                ToolsMicroAppListV30Response responseShare = api.openApiV30ToolsMicroAppListGet(qo.getAdvertiserId(), filteringShare, qo.getPageNum().intValue(), qo.getPageSize().intValue());
                ToolsMicroAppListV30ResponseData result = response.getData();

                respList.addAll(response.getData().getList());
                respList.addAll(responseShare.getData().getList());
            } else {
                return response.getData().getList();
            }
            return respList;
        } catch (Exception e) {
            throw new ServiceException("获取字节小程序失败," + e.getMessage());
        }
    }


    @Override
    public ToolsAssetLinkListV30ResponseData getToolsAssetLinkList(String accountId, GetToolsAssetLinkListPageQo req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsAssetLinkListV30Api api = new ToolsAssetLinkListV30Api();
            api.setApiClient(apiClient);
            ToolsAssetLinkListV30Filtering filtering = new ToolsAssetLinkListV30Filtering();
            filtering.setInstanceId(req.getInstanceId());
            ToolsAssetLinkListV30Response response = api.openApiV30ToolsAssetLinkListGet(req.getAdvertiserId(), filtering, null, null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取字节小程序详情失败," + e.getMessage());
        }
    }

    @Override
    public ToolsWechatAppletListV30ResponseData getToolsWechatAppletList(GetToolsWechatAppletListQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsWechatAppletListV30Api api = new ToolsWechatAppletListV30Api();
            api.setApiClient(apiClient);

            ToolsWechatAppletListV30Filtering filtering = new ToolsWechatAppletListV30Filtering();
            BeanUtil.copyProperties(qo, filtering);

            ToolsWechatAppletListV30Response response = api.openApiV30ToolsWechatAppletListGet(qo.getAdvertiserId(), filtering, qo.getPageNum().intValue(), qo.getPageSize().intValue());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取微信小程序失败," + e.getMessage());
        }
    }


    @Override
    public boolean shareDpAssetManagement(String accountId, ShareDpAssetManagementReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsBpAssetManagementShareV30Api api = new ToolsBpAssetManagementShareV30Api();
            api.setApiClient(apiClient);
            ToolsBpAssetManagementShareV30Request request = new ToolsBpAssetManagementShareV30Request();
            BeanUtil.copyProperties(req, request);

            ToolsBpAssetManagementShareV30Response response = api.openApiV30ToolsBpAssetManagementSharePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return true;
        } catch (Exception e) {
            throw new ServiceException("设置小游戏&小程序共享失败," + e.getMessage());
        }
    }

    @Override
    public boolean cancelShareDpAssetManagement(String accountId, ShareDpAssetManagementReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsBpAssetManagementShareCancelV30Api api = new ToolsBpAssetManagementShareCancelV30Api();
            api.setApiClient(apiClient);
            ToolsBpAssetManagementShareCancelV30Request request = new ToolsBpAssetManagementShareCancelV30Request();
            BeanUtil.copyProperties(req, request);

            ToolsBpAssetManagementShareCancelV30Response response = api.openApiV30ToolsBpAssetManagementShareCancelPost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return true;
        } catch (Exception e) {
            throw new ServiceException("取消小游戏&小程序共享失败," + e.getMessage());
        }
    }

    @Override
    public ToolsBpAssetManagementShareGetV30ResponseData getShareDpAssetManagement(String accountId, Long instanceId, ToolsBpAssetManagementShareGetV30AssetType assetTyp) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsBpAssetManagementShareGetV30Api api = new ToolsBpAssetManagementShareGetV30Api();
            api.setApiClient(apiClient);

            ToolsBpAssetManagementShareGetV30Response response = api.openApiV30ToolsBpAssetManagementShareGetGet(assetTyp, instanceId, Long.valueOf(accountId), null, null, null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("查看小游戏&小程序共享失败," + e.getMessage());
        }
    }

    @Override
    public ToolsEventAllAssetsListV2ResponseData getEventAllAssetsList(Long accountId, GetEventAllAssetsListPageQo qo) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);
            ToolsEventAllAssetsListV2Api api = new ToolsEventAllAssetsListV2Api();
            api.setApiClient(apiClient);

            ToolsEventAllAssetsListV2Filtering filtering = new ToolsEventAllAssetsListV2Filtering();
            filtering.setAssetIds(qo.getAssetIds());
            filtering.setAssetType(qo.getAssetType());
            filtering.setModifyStartTime(qo.getStartTime());
            filtering.setModifyEndTime(qo.getEndTime());
            ToolsEventAllAssetsListV2Response response = api.openApi2ToolsEventAllAssetsListGet(qo.getAdvertiserId(), filtering, qo.getPageNum().intValue(), qo.getPageSize().intValue());
            if (response.getCode().intValue() == 40100) {
                response = api.openApi2ToolsEventAllAssetsListGet(qo.getAdvertiserId(), filtering, qo.getPageNum().intValue(), qo.getPageSize().intValue());
            }
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取账户下资产列表（新）失败," + e.getMessage());
        }
    }

    @Override
    public List<ToolsEventAllAssetsDetailV2ResponseDataAssetListInner> getEventAllAssetsDetail(Long accountId, Long advertiserId, List<Long> assetIds) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);
            ToolsEventAllAssetsDetailV2Api api = new ToolsEventAllAssetsDetailV2Api();
            api.setApiClient(apiClient);

            ToolsEventAllAssetsDetailV2Response response = api.openApi2ToolsEventAllAssetsDetailGet(advertiserId, assetIds);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getAssetList();
        } catch (Exception e) {
            throw new ServiceException("获取已创建资产详情（新）失败," + e.getMessage());
        }
    }

    @Override
    public List<EventManagerEventConfigsGetV2ResponseDataEventConfigsInner> getEventManagerConfigs(Long accountId, GetEventManagerConfigsPageQo qo) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);
            EventManagerEventConfigsGetV2Api api = new EventManagerEventConfigsGetV2Api();
            api.setApiClient(apiClient);

            EventManagerEventConfigsGetV2Response response = api.openApi2EventManagerEventConfigsGetGet(qo.getAdvertiserId(), qo.getAssetId(), qo.getSortType());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getEventConfigs();
        } catch (Exception e) {
            throw new ServiceException("获取资产下已创建事件列表失败," + e.getMessage());
        }
    }

    @Override
    public List<EventManagerAvailableEventsGetV2ResponseDataEventConfigsInner> getEventManagerAvailableEventsList(Long accountId, Long advertiserId, Long assetId) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);
            EventManagerAvailableEventsGetV2Api api = new EventManagerAvailableEventsGetV2Api();
            api.setApiClient(apiClient);

            EventManagerAvailableEventsGetV2Response response = api.openApi2EventManagerAvailableEventsGetGet(advertiserId, assetId);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getEventConfigs();
        } catch (Exception e) {
            throw new ServiceException("获取可创建事件列表失败," + e.getMessage());
        }
    }

    @Override
    public boolean createEventManagerAssets(Long accountId, CreateEventManagerAssetsReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            EventManagerAssetsCreateV2Api api = new EventManagerAssetsCreateV2Api();
            api.setApiClient(apiClient);

            EventManagerAssetsCreateV2Request request = new EventManagerAssetsCreateV2Request();
            request.setAdvertiserId(req.getAdvertiserId());
            request.setAssetType(req.getAssetType());
            request.setMiniProgramAsset(BeanUtil.copyProperties(req.getMiniProgramAsset(), EventManagerAssetsCreateV2RequestMiniProgramAsset.class));
            EventManagerAssetsCreateV2Response response = api.openApi2EventManagerAssetsCreatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return true;
        } catch (Exception e) {
            throw new ServiceException("创建事件资产失败," + e.getMessage());
        }
    }

    @Override
    public boolean createEventManagerEvents(CreateEventManagerEventsReq req) {
        try {
            String accessToken = this.getAccessToken(req.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            EventManagerEventsCreateV2Api api = new EventManagerEventsCreateV2Api();
            api.setApiClient(apiClient);

            EventManagerEventsCreateV2Request request = new EventManagerEventsCreateV2Request();
            request.setAdvertiserId(req.getAdvertiserId());
            request.setAssetId(req.getAssetId());
            request.setEventId(req.getEventId());
            request.setTrackTypes(req.getTrackTypes());

            EventManagerEventsCreateV2Response response = api.openApi2EventManagerEventsCreatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return true;
        } catch (Exception e) {
            throw new ServiceException("资产下创建事件失败," + e.getMessage());
        }
    }


    @Override
    public FileImageAdV2ResponseData uploadImage(Long accountId, Long advertiserId, File file, String imageMd5) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            FileImageAdV2Api api = new FileImageAdV2Api();
            api.setApiClient(apiClient);

            FileImageAdV2Response response = api.openApi2FileImageAdPost(advertiserId, file.getName(), file, imageMd5, null, false, FileImageAdV2UploadType.FILE);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("上传广告图片失败," + e.getMessage());
        }
    }

    @Override
    public List<FileImageGetV2ResponseDataListInner> getImageList(Long accountId, Long advertiserId, Long page, Long pageSize) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            FileImageGetV2Api api = new FileImageGetV2Api();
            api.setApiClient(apiClient);

            List<FileVideoGetV2ResponseDataListInner> list = null;
            FileImageGetV2Response response = api.openApi2FileImageGetGet(advertiserId, null, page, pageSize);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData().getList();
        } catch (Exception e) {
            throw new ServiceException("获取视频素材失败," + e.getMessage());
        }
    }

    @Override
    public FileVideoAdV2ResponseData uploadVideo(Long accountId, UploadVideoReq req, File file) {
        String accessToken = this.getAccessToken(accountId + "");

        ApiClient apiClient = new ApiClient();
        apiClient.addDefaultHeader("Access-Token", accessToken);

        FileVideoAdV2Api api = new FileVideoAdV2Api();
        api.setApiClient(apiClient);

        List<FileVideoGetV2ResponseDataListInner> list = null;
        try {
            FileVideoAdV2Response response = api.openApi2FileVideoAdPost(req.getAdvertiserId(), req.getFile().getName(), false, false, req.getLabels(), FileVideoAdV2UploadType.FILE, file, req.getFileMd5(), null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("上传视频失败," + e.getMessage());
        }
    }

    @Override
    public FileVideoGetV2ResponseData getVideoList(GetVideoListQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            FileVideoGetV2Api api = new FileVideoGetV2Api();
            api.setApiClient(apiClient);

            FileVideoGetV2Filtering filtering = new FileVideoGetV2Filtering();
            BeanUtil.copyProperties(qo, filtering);
            if (ObjectUtils.isEmpty(qo.getStartTime())) {
                filtering.setStartTime(null);
            }
            if (ObjectUtils.isEmpty(qo.getEndTime())) {
                filtering.setEndTime(null);
            }
            if (qo.getSignatures() == null || qo.getSignatures().size() == 0) {
                filtering.setSignatures(null);
            }
            if (qo.getVideoIds() == null || qo.getVideoIds().size() == 0) {
                filtering.setVideoIds(null);
            }
            if (qo.getMaterialIds() == null || qo.getMaterialIds().size() == 0) {
                filtering.setMaterialIds(null);
            }
            if (!ObjectUtils.isEmpty(qo.getStartTime()) && qo.getStartTime().length() > 10) {
                filtering.setStartTime(qo.getStartTime().substring(0, 10));
            }
            if (!ObjectUtils.isEmpty(qo.getEndTime()) && qo.getEndTime().length() > 10) {
                filtering.setEndTime(qo.getEndTime().substring(0, 10));
            }

            FileVideoGetV2Response response = api.openApi2FileVideoGetGet(qo.getAdvertiserId(), filtering, qo.getPageNum(), qo.getPageSize());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取视频素材失败," + e.getMessage());
        }
    }

    @Override
    public FileImageGetV2ResponseData getImageList(GetImageListQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            FileImageGetV2Api api = new FileImageGetV2Api();
            api.setApiClient(apiClient);

            FileImageGetV2Filtering filtering = new FileImageGetV2Filtering();
            BeanUtil.copyProperties(qo, filtering);
            if (ObjectUtils.isEmpty(qo.getStartTime())) {
                filtering.setStartTime(null);
            }
            if (ObjectUtils.isEmpty(qo.getEndTime())) {
                filtering.setEndTime(null);
            }
            if (qo.getSignatures() == null || qo.getSignatures().size() == 0) {
                filtering.setSignatures(null);
            }
            if (qo.getImageIds() == null || qo.getImageIds().size() == 0) {
                filtering.setImageIds(null);
            }
            if (qo.getMaterialIds() == null || qo.getMaterialIds().size() == 0) {
                filtering.setMaterialIds(null);
            }

            FileImageGetV2Response response = api.openApi2FileImageGetGet(qo.getAdvertiserId(), filtering, qo.getPageNum(), qo.getPageSize());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取图片素材失败," + e.getMessage());
        }
    }

    @Override
    public FileMaterialAttributesListV2ResponseData getMaterialAttributesDetail(GetMaterialAttributesDetailQo qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            FileMaterialAttributesListV2Api api = new FileMaterialAttributesListV2Api();
            api.setApiClient(apiClient);

            FileMaterialAttributesListV2Filtering filtering = new FileMaterialAttributesListV2Filtering();
            BeanUtils.copyProperties(qo, filtering, "startTime", "endTime");
            if (!ObjectUtils.isEmpty(qo.getStartTime())) {
                filtering.setStartTime(qo.getStartTime());
            }
            if (!ObjectUtils.isEmpty(qo.getAttributesModifyTime())) {
                filtering.setEndTime(qo.getEndTime());
            }

            Long advertiserId = null;
            FileMaterialAttributesListV2AccountType accountType;
            if (!ObjectUtils.isEmpty(qo.getAdvertiserId())) {
                advertiserId = qo.getAdvertiserId();
                accountType = FileMaterialAttributesListV2AccountType.AD;
            } else {
                advertiserId = qo.getAccountId();
                accountType = FileMaterialAttributesListV2AccountType.BP;
            }

            FileMaterialAttributesListV2Response response = api.openApi2FileMaterialAttributesListGet(advertiserId, accountType, qo.getPageSize().intValue(), qo.getPageNum().intValue(), filtering, true);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取视频素材评估标签失败," + e.getMessage());
        }
    }

    @Override
    public void bindMaterial(BindMaterialReq req) {
        try {
            String accessToken = this.getAccessToken(req.getAccountId() + "");
            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            FileMaterialBindV2Api api = new FileMaterialBindV2Api();
            api.setApiClient(apiClient);

            FileMaterialBindV2Request request = new FileMaterialBindV2Request();
            request.setAdvertiserId(req.getAdvertiserId());
            request.setVideoIds(req.getVideoIds());
            request.setCarouselIds(req.getCarouselIds());
            request.setImageIds(req.getImageIds());
            request.setTargetAdvertiserIds(req.getTargetAdvertiserIds());
            FileMaterialBindV2Response response = api.openApi2FileMaterialBindPost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
        } catch (Exception e) {
            throw new ServiceException("素材推送失败," + e.getMessage());
        }
    }


    @Override
    public List<ProjectListV30ResponseDataListInner> projectList(Long accountId, Long advertiserId, List<String> fields, ProjectListV30Filtering filtering, Long page, Long pageSize) {
        String accessToken = this.getAccessToken(accountId + "");

        ApiClient apiClient = new ApiClient();
        apiClient.addDefaultHeader("Access-Token", accessToken);

        ProjectListV30Api api = new ProjectListV30Api();
        api.setApiClient(apiClient);
        try {
            ProjectListV30Response response = api.openApiV30ProjectListGet(advertiserId, new ArrayList<>(), filtering, page, pageSize);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            List<ProjectListV30ResponseDataListInner> list = response.getData().getList();
            return list;
        } catch (Exception e) {
            throw new ServiceException("查询项目失败," + e.getMessage());
        }
    }

    @Override
    public boolean createToolsSite(String accountId, CreateToolsSiteCreateV2Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsSiteCreateV2Api api = new ToolsSiteCreateV2Api();
            api.setApiClient(apiClient);

            ToolsSiteCreateV2Request request = new ToolsSiteCreateV2Request();

            BeanUtil.copyProperties(req, request);
            ToolsSiteCreateV2Response response = api.openApi2ToolsSiteCreatePost("", request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("创建字节小程序失败," + e.getMessage());
        }
    }

    @Override
    public boolean updateToolsSite(String accountId, UpdateToolsSiteCreateV2Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsSiteUpdateV2Api api = new ToolsSiteUpdateV2Api();
            api.setApiClient(apiClient);

            ToolsSiteUpdateV2Request request = new ToolsSiteUpdateV2Request();

            BeanUtil.copyProperties(req, request);
            ToolsSiteUpdateV2Response response = api.openApi2ToolsSiteUpdatePost("", request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("修改字节小程序失败," + e.getMessage());
        }
    }

    @Override
    public boolean updateStatusToolsSite(String accountId, UpdateStatusToolsSiteCreateV2Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsSiteUpdateStatusV2Api api = new ToolsSiteUpdateStatusV2Api();
            api.setApiClient(apiClient);

            ToolsSiteUpdateStatusV2Request request = new ToolsSiteUpdateStatusV2Request();

            BeanUtil.copyProperties(req, request);
            ToolsSiteUpdateStatusV2Response response = api.openApi2ToolsSiteUpdateStatusPost("", request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("更改橙子建站站点状态失败," + e.getMessage());
        }
    }

    @Override
    public ToolsSitePreviewV2Response getToolsSitePreview(Long advertiserId, String accountId, String siteId) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsSitePreviewV2Api api = new ToolsSitePreviewV2Api();
            api.setApiClient(apiClient);

            ToolsSitePreviewV2Response response = api.openApi2ToolsSitePreviewGet(advertiserId, siteId, null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response;
        } catch (Exception e) {
            throw new ServiceException("获取橙子建站站点预览地址失败," + e.getMessage());
        }
    }

    @Override
    public ToolsSiteReadV2Response getToolsSiteRead(Long advertiserId, String accountId, String siteId) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsSiteReadV2Api api = new ToolsSiteReadV2Api();
            api.setApiClient(apiClient);

            ToolsSiteReadV2Response response = api.openApi2ToolsSiteReadGet(null, advertiserId.toString(), siteId);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response;
        } catch (Exception e) {
            throw new ServiceException("获取橙子建站站点详细信息失败," + e.getMessage());
        }
    }

    @Override
    public ToolsSiteGetV2ResponseData getToolsSiteList(Long accountId, ToolsSiteListV2Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsSiteGetV2Api api = new ToolsSiteGetV2Api();
            api.setApiClient(apiClient);
            ToolsSiteGetV2Filtering filtering = new ToolsSiteGetV2Filtering();
            filtering.setSearch(req.getSearch());
            ToolsSiteGetV2Response response = api.openApi2ToolsSiteGetGet(req.getAdvertiserId(), null, req.getPageNum(), req.getPageSize(), req.getStatus(), req.getShareType(), filtering);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取橙子建站站点详细信息失败," + e.getMessage());
        }
    }

    @Override
    public boolean createNativeAnchor(String accountId, CreateNativeAnchorV3Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            NativeAnchorCreateV30Api api = new NativeAnchorCreateV30Api();
            api.setApiClient(apiClient);

            NativeAnchorCreateV30Request request = new NativeAnchorCreateV30Request();

            BeanUtil.copyProperties(req, request);
            NativeAnchorCreateV30Response response = api.openApiV30NativeAnchorCreatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("创建原生锚点失败," + e.getMessage());
        }
    }

    @Override
    public boolean updateNativeAnchor(String accountId, UpdateNativeAnchorV3Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            NativeAnchorUpdateV30Api api = new NativeAnchorUpdateV30Api();
            api.setApiClient(apiClient);

            NativeAnchorUpdateV30Request request = new NativeAnchorUpdateV30Request();

            BeanUtil.copyProperties(req, request);
            NativeAnchorUpdateV30Response response = api.openApiV30NativeAnchorUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("更新原生锚点失败," + e.getMessage());
        }
    }

    @Override
    public boolean deleteNativeAnchor(String accountId, Long advertiserId, String anchorId) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            NativeAnchorDeleteV30Api api = new NativeAnchorDeleteV30Api();
            api.setApiClient(apiClient);

            NativeAnchorDeleteV30Request request = new NativeAnchorDeleteV30Request();
            request.setAdvertiserId(advertiserId);
            request.setAnchorId(anchorId);

            NativeAnchorDeleteV30Response response = api.openApiV30NativeAnchorDeletePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("删除原生锚点失败," + e.getMessage());
        }
    }

    @Override
    public NativeAnchorGetV30Response getNativeAnchor(GetNativeAnchorV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            NativeAnchorGetV30Api api = new NativeAnchorGetV30Api();
            api.setApiClient(apiClient);

            NativeAnchorGetV30Filtering filtering = new NativeAnchorGetV30Filtering();
            filtering.setAnchorId(qo.getAnchorId());

            NativeAnchorGetV30Response response = api.openApiV30NativeAnchorGetGet(qo.getAdvertiserId(), qo.getPageNum().intValue(), qo.getPageSize().intValue(), filtering);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response;
        } catch (Exception e) {
            throw new ServiceException("获取原生锚点列表失败," + e.getMessage());
        }
    }

    @Override
    public NativeAnchorGetDetailV30ResponseData getNativeAnchorDetail(GetDetailNativeAnchorV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            NativeAnchorGetDetailV30Api api = new NativeAnchorGetDetailV30Api();
            api.setApiClient(apiClient);
            NativeAnchorGetDetailV30Response response = api.openApiV30NativeAnchorGetDetailGet(qo.getAnchorIds(), qo.getAdvertiserId(), qo.getAnchorType());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取原生锚点详情失败," + e.getMessage());
        }
    }

    @Override
    public NativeAnchorQrcodePreviewGetV30ResponseData getNativeAnchorQrcode(GetDetailNativeAnchorV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            NativeAnchorQrcodePreviewGetV30Api api = new NativeAnchorQrcodePreviewGetV30Api();
            api.setApiClient(apiClient);
            NativeAnchorQrcodePreviewGetV30AnchorType type = NativeAnchorQrcodePreviewGetV30AnchorType.valueOf(qo.getAnchorType().name());
            NativeAnchorQrcodePreviewGetV30Response response = api.openApiV30NativeAnchorQrcodePreviewGetGet(qo.getAdvertiserId(), qo.getAnchorIds(), type);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取原生锚点详情失败," + e.getMessage());
        }
    }

    @Override
    public Long createProject(Long accountId, ProjectCreateV30Request2 req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ProjectCreateV30Api api = new ProjectCreateV30Api();
            api.setApiClient(apiClient);

            ProjectCreateV30Request request = new ProjectCreateV30Request();
            BeanUtil.copyProperties(req, request);

            ProjectCreateV30Response response = api.openApiV30ProjectCreatePost(request);
            if (response.getCode() != 0) {
                log.info("广告主：{}，创建项目失败：{}", req.getAdvertiserId(), response.getMessage());
                throw new ServiceException(response.getMessage());
            }
            log.info("广告主：{}，创建项目成功。", req.getAdvertiserId());
            return response.getData().getProjectId();
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }

    //TODO
    @Override
    public R createProjectPromotion(Long accountId, CreateProjectPromotionQo req, String appCode) {
        List<Long> advertiserIds = req.getAdvertiserIds();
        for (Long advertiserId : advertiserIds) {
            AdvertiserAvatarGetV2ResponseData avatar = queryAdvertiserAvatar(advertiserId, appCode);
            if (ObjectUtils.isEmpty(avatar.getAvatarInfo().getWebUri()) || avatar.getAvatarInfo().getWebUri() == null) {
                throw new ServiceException("当前广告主用户没有头像，请前去修改。广告主Id：" + advertiserId + "-" + translateStatus(avatar.getAvatarStatus()));
            }
        }
        //投手名
        String name = LoginHelper.getLoginUser().getRemark() == null ? "管理员" : LoginHelper.getLoginUser().getRemark();
        //落地页分配方式 1全部相同    2按账户分配
        Integer number = 1;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M.d"); // 月.日，无前导零
        String currentDate = LocalDate.now().format(formatter);

        //循环多个广告主创建广告
        StringBuffer projectErrorMsg = new StringBuffer();
        StringBuffer promotionErrorMsg = new StringBuffer();

        //广告信息
        CreatePromotionV3Request promotion = req.getPromotion();
        for (Long adId : advertiserIds) {
            //创意组
            List<CreatePromotionGroupQo> groupQosAd = req.getGroupQos();
            if ("3".equals(req.getMaterialType())) {
                groupQosAd = req.getGroupQos().stream().filter(g -> g.getAdvertiserId().equals(adId)).collect(Collectors.toList());
            }
            //标题包
            List<CreateTitleWrapQo> titleWrapList = req.getTitleWrap();
            if ("3".equals(req.getTitleWay())) {
                titleWrapList = req.getTitleWrap().stream().filter(g -> g.getAdvertiserId().equals(adId)).collect(Collectors.toList());
            }
            if (titleWrapList == null || titleWrapList.size() == 0) {
                throw new ServiceException("广告主：" + adId + "没有选择标题包");
            }

//            AnchorMaterialReq anchorMaterialReq = null;
            if (req.isWechat()) {
//                anchorMaterialReq = req.getAnchorMaterialList().stream().filter(item -> item.getAdvertiserId().longValue() == adId.longValue()).findFirst().get();
                //临时写死
                promotion.getNativeSetting().setAnchorRelatedType(PromotionCreateV30NativeSettingAnchorRelatedType.AUTO);
            } else if (req.isDouYinHao()) {
                promotion.getNativeSetting().setAnchorRelatedType(null);
            }

            //分账户取落地页
            List<CreatePromotionUrlQo> ldyListAdId = new ArrayList<>();
            if ("2".equals(req.getSiteWay())) {
                ldyListAdId = req.getExternalUrlMaterialList().stream().filter(g -> g.getAdvertiserId().equals(adId)).collect(Collectors.toList());
            } else {
                ldyListAdId = req.getExternalUrlMaterialList();
            }
            Optional<CreatePromotionUrlQo> first = ldyListAdId.stream().filter(item -> item.getAdvertiserId().equals(adId)).findFirst();
            if (first.isEmpty() || first.get() == null) {
                throw new ServiceException("未找到广告主：" + adId + "的落地页");
            }
            CreatePromotionUrlQo createPromotionUrlQo = first.get();

            MicroAppInstanceReq microAppInstanceReq = null;
            if (req.isWechat() || req.isByte()) {
                //分账号取小程序载体
                Optional<MicroAppInstanceReq> appFirst = req.getMicroAppInstanceList().stream().filter(item -> item.getAdvertiserId().equals(adId)).findFirst();
                if (appFirst.isEmpty() || appFirst.get() == null) {
                    throw new ServiceException("未找到广告主：" + adId + "小程序载体");
                }
                microAppInstanceReq = appFirst.get();
            }


            //商品名称
            String productName = promotion.getPromotionMaterials().getProductInfo().getTitles().get(0);
            for (int projectNum = 0; projectNum < req.getProjectNum(); projectNum++) {
                try {
                    ProjectCreateV30Request2 project = BeanUtil.copyProperties(req.getProject(), ProjectCreateV30Request2.class);
                    if (ObjectUtils.isEmpty(req.getProjectId())) {
                        String projectName2 = req.getProject().getName().replace("<日期>", currentDate).replace("<花名>", name).toString().replace("<剧名>", productName).replace("<编号>", String.valueOf(number));
                        project.setName(projectName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                    }
                    number++;
                    project.setAdvertiserId(adId);
                    if (req.isWechat() || req.isByte()) {
                        project.setMicroAppInstanceId(microAppInstanceReq.getMicroAppInstanceId());
                        if (req.isByte() && !ObjectUtils.isEmpty(microAppInstanceReq.getAssetId())) {
                            project.getOptimizeGoal().setAssetIds(Arrays.asList(microAppInstanceReq.getAssetId()));
                        }
                    }
                    //创建项目
                    Long projectId = req.getProjectId();
                    if (ObjectUtils.isEmpty(projectId)) {
                        projectId = createProject(accountId, project);
                    }

                    CreatePromotionV3Request addPromotion = BeanUtil.copyProperties(req.getPromotion(), CreatePromotionV3Request.class);
                    addPromotion.setAdvertiserId(adId);
                    addPromotion.setProjectId(projectId);
                    PromotionCreateV30RequestPromotionMaterials promotionMaterials = addPromotion.getPromotionMaterials();

                    if (req.isByte()) {//填充字节小程序
                        List<CreatePromotionUrlQo> url = req.getUrls().stream().filter(u -> u.getAdvertiserId().equals(adId)).collect(Collectors.toList());
                        if (url != null && !url.isEmpty()) {
                            PromotionCreateV30RequestPromotionMaterialsMiniProgramInfo miniProgramInfo = new PromotionCreateV30RequestPromotionMaterialsMiniProgramInfo();
                            if (!ObjectUtils.isEmpty(url.get(0).getUrl())) {
                                miniProgramInfo.setUrl(url.get(0).getUrl().trim());
                            } else {
                                miniProgramInfo.setParams(url.get(0).getParams().trim());
                                miniProgramInfo.setStartPath(url.get(0).getStartPath().trim());
                                miniProgramInfo.setAppId(url.get(0).getAppId().trim());
                            }
                            promotionMaterials.setMiniProgramInfo(miniProgramInfo);
                        }
                    }

                    if (req.isDouYinHao()) {//抖音号专辑链接
                        promotionMaterials.setPlayletSeriesUrlList(Arrays.asList(createPromotionUrlQo.getUrl().trim()));
                    } else {//微小落地页链接、字节小程序链接
                        promotionMaterials.setExternalUrlMaterialList(Arrays.asList(createPromotionUrlQo.getUrl().trim()));
                    }
                    if (req.isWechat()) {//微信锚点
//                        PromotionCreateV30RequestPromotionMaterialsAnchorMaterialListInner anchor = BeanUtil.copyProperties(anchorMaterialReq, PromotionCreateV30RequestPromotionMaterialsAnchorMaterialListInner.class);
//                        promotionMaterials.setAnchorMaterialList(Arrays.asList(anchor));
                    }

                    int adNum = 1;
                    if (1 == req.getProjectAdRule()) {//广告生成规则  1按创意组数
                        for (int groupNum = 0; groupNum < groupQosAd.size(); groupNum++) {
                            try {
                                CreatePromotionGroupQo group = groupQosAd.get(groupNum);
                                promotionMaterials.setVideoMaterialList(group.getVideoMaterialList());
//                                promotionMaterials.setImageMaterialList(group.getImageMaterialList());
                                CreateTitleWrapQo title = titleWrapList.get(groupNum % titleWrapList.size());
                                promotionMaterials.setTitleMaterialList(title.getTitles());
                                //创建广告
                                String promotionName2 = req.getPromotion().getName().replace("<日期>", currentDate).replace("<花名>", name).replace("<剧名>", productName).replace("<编号>", String.valueOf(adNum));
                                addPromotion.setName(promotionName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                                createPromotion(accountId, addPromotion);
                                adNum = adNum + 1;
                            } catch (Exception e) {
                                promotionErrorMsg.append("项目id=" + projectId + ",广告序号：" + adNum + ",错误信息：" + e.getMessage());
                            }
                        }
                    } else if (2 == req.getProjectAdRule()) {//2按创意组*标题包
                        for (CreatePromotionGroupQo group : groupQosAd) {
                            for (int titleWrapNum = 0; titleWrapNum < req.getTitleWrap().size(); titleWrapNum++) {
                                try {
                                    promotionMaterials.setVideoMaterialList(group.getVideoMaterialList());
                                    CreateTitleWrapQo title = titleWrapList.get(titleWrapNum);
                                    promotionMaterials.setTitleMaterialList(title.getTitles());
                                    //创建广告
                                    String promotionName2 = req.getPromotion().getName().replace("<日期>", currentDate).replace("<花名>", name).replace("<剧名>", productName).replace("<编号>", String.valueOf(adNum));
                                    addPromotion.setName(promotionName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                                    adNum = adNum + 1;
                                    createPromotion(accountId, addPromotion);
                                } catch (Exception e) {
                                    promotionErrorMsg.append("项目id=" + projectId + ",广告序号：" + adNum + ",错误信息：" + e.getMessage());
                                }
                            }
                        }
                    } else if (3 == req.getProjectAdRule()) {//3指定数量
                        for (int proNum = 0; proNum < req.getPromotionNum(); proNum++) {
                            try {
                                CreatePromotionGroupQo group = groupQosAd.get(proNum % groupQosAd.size());
                                promotionMaterials.setVideoMaterialList(group.getVideoMaterialList());
//                                promotionMaterials.setImageMaterialList(group.getImageMaterialList());

                                CreateTitleWrapQo title = titleWrapList.get(proNum % titleWrapList.size());
                                promotionMaterials.setTitleMaterialList(title.getTitles());

                                //创建广告
                                String promotionName2 = req.getPromotion().getName().replace("<日期>", currentDate).replace("<花名>", name).replace("<剧名>", productName).replace("<编号>", String.valueOf(adNum));
                                addPromotion.setName(promotionName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                                adNum = adNum + 1;
                                createPromotion(accountId, addPromotion);
                            } catch (Exception e) {
                                promotionErrorMsg.append("项目id=" + projectId + ",广告序号：" + adNum + ",错误信息：" + e.getMessage());
                            }
                        }
                    }
                    //打乱标题包
                    Collections.shuffle(titleWrapList);
                } catch (Exception e) {
                    log.info("创建项目失败，第{}个项目,{}", projectNum + 1, e.getMessage());
                    projectErrorMsg.append("创建第" + (projectNum + 1) + "个项目失败，" + e.getMessage());
                }
            }
        }
        if (!ObjectUtils.isEmpty(projectErrorMsg.toString()) || !ObjectUtils.isEmpty(promotionErrorMsg.toString())) {
            throw new ServiceException(projectErrorMsg.toString() + " |||| " + promotionErrorMsg.toString());
        }
        return R.ok();
    }

    @Override
    public R<List<ProjectPromotionAggregation>> createProjectPromotionPreview(Long accountId, CreateProjectPromotionQo req, String appCode) {
        boolean flag = Boolean.TRUE;
        List<Long> advertiserIds = req.getAdvertiserIds();
        for (Long advertiserId : advertiserIds) {
            AdvertiserAvatarGetV2ResponseData avatar = queryAdvertiserAvatar(advertiserId, appCode);
            if (ObjectUtils.isEmpty(avatar.getAvatarInfo().getWebUri()) || avatar.getAvatarInfo().getWebUri() == null) {
                throw new ServiceException("当前广告主用户没有头像，请前去修改。广告主Id：" + advertiserId + "-" + translateStatus(avatar.getAvatarStatus()));
            }
        }
        //投手名
        String name = LoginHelper.getLoginUser().getRemark() == null ? "管理员" : LoginHelper.getLoginUser().getRemark();
        Integer number = 1;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M.d"); // 月.日，无前导零
        String currentDate = LocalDate.now().format(formatter);
        List<ProjectPromotionAggregation> addTaskList = new ArrayList<>();

        //循环多个广告主创建广告
        StringBuffer projectErrorMsg = new StringBuffer();
        StringBuffer promotionErrorMsg = new StringBuffer();

        //广告信息
        CreatePromotionV3Request promotion = req.getPromotion();
        for (Long adId : advertiserIds) {
            ProjectPromotionAggregation promotionAggregation = new ProjectPromotionAggregation();
            promotionAggregation.setAdvertiserId(adId);

            addTaskList.add(promotionAggregation);
            List<ProjectCreateV30Request2> projectList = new ArrayList<>();
            promotionAggregation.setProjectList(projectList);

            //创意组
            List<CreatePromotionGroupQo> groupQosAd = req.getGroupQos();
            if ("3".equals(req.getMaterialType())) {
                groupQosAd = req.getGroupQos().stream().filter(g -> g.getAdvertiserId().equals(adId)).collect(Collectors.toList());
            }
            //标题包
            List<CreateTitleWrapQo> titleWrapList = req.getTitleWrap();
            if ("3".equals(req.getTitleWay())) {
                titleWrapList = req.getTitleWrap().stream().filter(g -> g.getAdvertiserId().equals(adId)).collect(Collectors.toList());
            }
            if (titleWrapList == null || titleWrapList.size() == 0) {
                throw new ServiceException("广告主：" + adId + "没有选择标题包");
            }

//            AnchorMaterialReq anchorMaterialReq = null;
            if (req.isWechat()) {
//                anchorMaterialReq = req.getAnchorMaterialList().stream().filter(item -> item.getAdvertiserId().equals(adId)).findFirst().get();
                //临时写死
                promotion.getNativeSetting().setAnchorRelatedType(PromotionCreateV30NativeSettingAnchorRelatedType.AUTO);
            } else if (req.isDouYinHao()) {
                promotion.getNativeSetting().setAnchorRelatedType(null);
            }

            //分账户取落地页
            List<CreatePromotionUrlQo> ldyListAdId = new ArrayList<>();
            if ("2".equals(req.getSiteWay())) {
                ldyListAdId = req.getExternalUrlMaterialList().stream().filter(g -> g.getAdvertiserId().equals(adId)).collect(Collectors.toList());
            } else {
                ldyListAdId = req.getExternalUrlMaterialList();
            }
            Optional<CreatePromotionUrlQo> first = ldyListAdId.stream().filter(item -> item.getAdvertiserId().equals(adId)).findFirst();
            if (first.isEmpty() || first.get() == null) {
                throw new ServiceException("未找到广告主：" + adId + "的落地页");
            }
            CreatePromotionUrlQo createPromotionUrlQo = first.get();

            MicroAppInstanceReq microAppInstanceReq = null;
            if (req.isWechat() || req.isByte()) {
                //分账号取小程序载体
                Optional<MicroAppInstanceReq> appFirst = req.getMicroAppInstanceList().stream().filter(item -> item.getAdvertiserId().equals(adId)).findFirst();
                if (appFirst.isEmpty() || appFirst.get() == null) {
                    throw new ServiceException("未找到广告主：" + adId + "小程序载体");
                }
                microAppInstanceReq = appFirst.get();
            }

            //商品名称
            String productName = promotion.getPromotionMaterials().getProductInfo().getTitles().get(0);
            for (int projectNum = 0; projectNum < req.getProjectNum(); projectNum++) {
                try {
                    Thread.sleep(2);
                    ProjectCreateV30Request2 project = BeanUtil.copyProperties(req.getProject(), ProjectCreateV30Request2.class);
                    if (ObjectUtils.isEmpty(req.getProjectId())) {
                        String projectName2 = req.getProject().getName().replace("<日期>", currentDate).replace("<花名>", name).toString().replace("<剧名>", productName).replace("<编号>", String.valueOf(number));
                        project.setName(projectName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                    }
                    number++;
                    project.setAdvertiserId(adId);
                    if (req.isWechat() || req.isByte()) {
                        project.setMicroAppInstanceId(microAppInstanceReq.getMicroAppInstanceId());
                        if (req.isByte() && !ObjectUtils.isEmpty(microAppInstanceReq.getAssetId())) {
                            project.getOptimizeGoal().setAssetIds(Arrays.asList(microAppInstanceReq.getAssetId()));
                        }
                    }
                    //创建项目
//                    Long projectId = createProject(accountId, project);
                    project.setProjectId(req.getProjectId());
                    projectList.add(project);

                    //待组装的广告集合
                    List<CreatePromotionV3Request> promotionList = new ArrayList<>();
                    project.setPromotionList(promotionList);


                    PromotionCreateV30RequestPromotionMaterials promotionMaterials = req.getPromotion().getPromotionMaterials();
                    if (req.isByte()) {//填充字节小程序
                        List<CreatePromotionUrlQo> url = req.getUrls().stream().filter(u -> u.getAdvertiserId().equals(adId)).collect(Collectors.toList());
                        if (url != null && !url.isEmpty()) {
                            PromotionCreateV30RequestPromotionMaterialsMiniProgramInfo miniProgramInfo = new PromotionCreateV30RequestPromotionMaterialsMiniProgramInfo();
                            if (!ObjectUtils.isEmpty(url.get(0).getUrl())) {
                                miniProgramInfo.setUrl(url.get(0).getUrl().trim());
                            } else {
                                miniProgramInfo.setParams(url.get(0).getParams().trim());
                                miniProgramInfo.setStartPath(url.get(0).getStartPath().trim());
                                miniProgramInfo.setAppId(url.get(0).getAppId().trim());
                            }
                            promotionMaterials.setMiniProgramInfo(miniProgramInfo);
                        }
                    }

                    if (req.isDouYinHao()) {//抖音号专辑链接
                        promotionMaterials.setPlayletSeriesUrlList(Arrays.asList(createPromotionUrlQo.getUrl().trim()));
                    } else {//微小落地页链接、字节小程序链接
                        promotionMaterials.setExternalUrlMaterialList(Arrays.asList(createPromotionUrlQo.getUrl().trim()));
                    }
                    if (req.isWechat()) {//微信锚点
//                        PromotionCreateV30RequestPromotionMaterialsAnchorMaterialListInner anchor = BeanUtil.copyProperties(anchorMaterialReq, PromotionCreateV30RequestPromotionMaterialsAnchorMaterialListInner.class);
//                        promotionMaterials.setAnchorMaterialList(Arrays.asList(anchor));
                    }


                    int adNum = 1;
                    if (1 == req.getProjectAdRule()) {//广告生成规则  1按创意组数
                        for (int groupNum = 0; groupNum < groupQosAd.size(); groupNum++) {
                            Thread.sleep(2);
                            CreatePromotionV3Request addPromotion = new CreatePromotionV3Request();
                            BeanUtil.copyProperties(req.getPromotion(), addPromotion);
                            addPromotion.setAdvertiserId(adId);
                            addPromotion.setProjectId(req.getProjectId());

                            PromotionCreateV30RequestPromotionMaterials addPromotionMaterials = BeanUtil.copyProperties(promotionMaterials, PromotionCreateV30RequestPromotionMaterials.class);
                            addPromotion.setPromotionMaterials(addPromotionMaterials);

                            CreatePromotionGroupQo group = groupQosAd.get(groupNum);
                            addPromotionMaterials.setVideoMaterialList(group.getVideoMaterialList());

                            CreateTitleWrapQo title = titleWrapList.get(groupNum % titleWrapList.size());
                            addPromotionMaterials.setTitleMaterialList(title.getTitles());
                            addPromotion.setTitleWrapName(title.getName());
                            //创建广告
                            String promotionName2 = req.getPromotion().getName().replace("<日期>", currentDate).replace("<花名>", name).replace("<剧名>", productName).replace("<编号>", String.valueOf(adNum));
                            addPromotion.setName(promotionName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                            adNum = adNum + 1;
//                          createPromotion(accountId, promotion);
                            promotionList.add(addPromotion);
                        }
                    } else if (2 == req.getProjectAdRule()) {//2按创意组*标题包
                        for (CreatePromotionGroupQo group : groupQosAd) {
                            for (int titleWrapNum = 0; titleWrapNum < titleWrapList.size(); titleWrapNum++) {
                                Thread.sleep(2);
                                CreatePromotionV3Request addPromotion = BeanUtil.copyProperties(req.getPromotion(), CreatePromotionV3Request.class);
                                addPromotion.setAdvertiserId(adId);
                                addPromotion.setProjectId(req.getProjectId());

                                PromotionCreateV30RequestPromotionMaterials addPromotionMaterials = BeanUtil.copyProperties(promotionMaterials, PromotionCreateV30RequestPromotionMaterials.class);
                                addPromotion.setPromotionMaterials(addPromotionMaterials);
                                addPromotionMaterials.setVideoMaterialList(group.getVideoMaterialList());

                                CreateTitleWrapQo title = titleWrapList.get(titleWrapNum);
                                addPromotion.getPromotionMaterials().setTitleMaterialList(title.getTitles());
                                addPromotion.setTitleWrapName(title.getName());
                                //创建广告
                                String promotionName2 = req.getPromotion().getName().replace("<日期>", currentDate).replace("<花名>", name).replace("<剧名>", productName).replace("<编号>", String.valueOf(adNum));
                                addPromotion.setName(promotionName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                                adNum = adNum + 1;
//                              createPromotion(accountId, promotion);
                                promotionList.add(addPromotion);
                            }
                        }
                    } else if (3 == req.getProjectAdRule()) {//3指定数量
                        for (int proNum = 0; proNum < req.getPromotionNum(); proNum++) {
                            Thread.sleep(2);
                            CreatePromotionV3Request addPromotion = BeanUtil.copyProperties(req.getPromotion(), CreatePromotionV3Request.class);
                            addPromotion.setAdvertiserId(adId);
                            addPromotion.setProjectId(req.getProjectId());

                            PromotionCreateV30RequestPromotionMaterials addPromotionMaterials = BeanUtil.copyProperties(promotionMaterials, PromotionCreateV30RequestPromotionMaterials.class);
                            addPromotion.setPromotionMaterials(addPromotionMaterials);

                            CreatePromotionGroupQo group = groupQosAd.get(proNum % groupQosAd.size());
                            addPromotionMaterials.setVideoMaterialList(group.getVideoMaterialList());

                            CreateTitleWrapQo title = titleWrapList.get(proNum % titleWrapList.size());
                            addPromotion.getPromotionMaterials().setTitleMaterialList(title.getTitles());
                            addPromotion.setTitleWrapName(title.getName());

                            //创建广告
                            String promotionName2 = req.getPromotion().getName().replace("<日期>", currentDate).replace("<花名>", name).replace("<剧名>", productName).replace("<编号>", String.valueOf(adNum));
                            addPromotion.setName(promotionName2 + "-" + DateUtil.format(new Date(), "HH_mm_ss_SSS"));
                            adNum = adNum + 1;
//                          createPromotion(accountId, promotion);
                            promotionList.add(addPromotion);
                        }
                    }
                    //打乱标题包
                    Collections.shuffle(titleWrapList);
                } catch (Exception e) {
                    log.info("创建项目失败，第{}个项目,{}", projectNum + 1, e.getMessage());
                    projectErrorMsg.append("创建第" + (projectNum + 1) + "个项目失败，" + e.getMessage());
                }
            }
        }
        if (!ObjectUtils.isEmpty(projectErrorMsg.toString()) || !ObjectUtils.isEmpty(promotionErrorMsg.toString())) {
            throw new ServiceException(projectErrorMsg.toString() + " |||| " + promotionErrorMsg.toString());
        }
        return R.ok(addTaskList);
    }

    @Override
    public ToolsAdminInfoV2ResponseData getAdminInfo(GetAdminInfoV2Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsAdminInfoV2Api api = new ToolsAdminInfoV2Api();
            api.setApiClient(apiClient);

            ToolsAdminInfoV2Response response = api.openApi2ToolsAdminInfoGet(qo.getAdvertiserId(), qo.getCodes(), qo.getLanguage(), qo.getSubDistrict());
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取行政信息失败," + e.getMessage());
        }
    }

    @Override
    public ProjectListV30ResponseData getProjectList(String accountId, Long advertiserId, List<Long> ids, ProjectListV30FilteringStatus status, Long pageNum, Long pageSize) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ProjectListV30Api api = new ProjectListV30Api();
            api.setApiClient(apiClient);

            ProjectListV30Filtering filtering = new ProjectListV30Filtering();
            filtering.setIds(ids);
            filtering.setStatus(status);
            ProjectListV30Response response = api.openApiV30ProjectListGet(advertiserId, null, filtering, pageNum, pageSize);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取项目列表失败," + e.getMessage());
        }
    }

    @Override
    public boolean updateProject(String accountId, UpdateProjectV3Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ProjectUpdateV30Api api = new ProjectUpdateV30Api();
            api.setApiClient(apiClient);

            ProjectUpdateV30Request request = new ProjectUpdateV30Request();

            BeanUtil.copyProperties(req, request);
            ProjectUpdateV30Response response = api.openApiV30ProjectUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("更新项目失败," + e.getMessage());
        }
    }

    @Override
    public EventManagerOptimizedGoalGetV2V30ResponseData getEventManagerOptimizedGoal(GetEventManagerV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            EventManagerOptimizedGoalGetV2V30Api api = new EventManagerOptimizedGoalGetV2V30Api();
            api.setApiClient(apiClient);

            EventManagerOptimizedGoalGetV2V30Response response = api.openApiV30EventManagerOptimizedGoalGetV2Get(qo.getAdvertiserId(), qo.getLandingType(), qo.getAdType(), qo.getAssetType(), qo.getAssetId(), null, null, null, null, null, qo.getDeliveryMode(), qo.getMiniProgramId(), null, null, qo.getMicroAppInstanceId(), null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取可用优化目标（巨量广告升级版）失败," + e.getMessage());
        }
    }

    @Override
    public EventManagerDeepBidTypeGetV30ResponseData getEventManagerDeepBidType(GetEventManagerDeepBidTypeV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            EventManagerDeepBidTypeGetV30Api api = new EventManagerDeepBidTypeGetV30Api();
            api.setApiClient(apiClient);


            EventManagerDeepBidTypeGetV30Response response = api.openApiV30EventManagerDeepBidTypeGetGet(qo.getAdvertiserId(), qo.getExternalAction(), null, qo.getDeepExternalAction(), null, null, null, null, null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取可用深度优化方式（广告投放升级版）失败," + e.getMessage());
        }
    }

    @Override
    public Boolean updateProjectStats(UpdateProjectStatusV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ProjectStatusUpdateV30Api api = new ProjectStatusUpdateV30Api();
            api.setApiClient(apiClient);
            ProjectStatusUpdateV30Request request = new ProjectStatusUpdateV30Request();
            BeanUtil.copyProperties(qo, request);


            ProjectStatusUpdateV30Response response = api.openApiV30ProjectStatusUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("批量更新项目状态失败," + e.getMessage());
        }
    }

    @Override
    public ProjectDeleteV30ResponseData deleteProject(DeleteProjectV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ProjectDeleteV30Api api = new ProjectDeleteV30Api();
            api.setApiClient(apiClient);
            ProjectDeleteV30Request request = new ProjectDeleteV30Request();
            BeanUtil.copyProperties(qo, request);


            ProjectDeleteV30Response response = api.openApiV30ProjectDeletePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("批量删除项目状态失败," + e.getMessage());
        }
    }

    @Override
    public boolean createPromotion(Long accountId, CreatePromotionV3Request req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            PromotionCreateV30Api api = new PromotionCreateV30Api();
            api.setApiClient(apiClient);//QPS=10

            PromotionCreateV30Request request = new PromotionCreateV30Request();
            BeanUtil.copyProperties(req, request);

            PromotionCreateV30Response response = null;
            int maxNum = 0;
            do {
                response = api.openApiV30PromotionCreatePost(request);
                if (response.getCode() != 0) {
                    log.info("创建广告失败,项目id={}，{}", req.getProjectId(), JSONUtil.toJsonStr(response));
                }
                maxNum = maxNum + 1;
            } while ((response.getCode().intValue() == 40100 || response.getCode().intValue() == 50000 || response.getCode().intValue() == 51010) && maxNum <= 5);
            if (response.getCode() != 0) {
                log.info("创建广告失败,项目id={}，{}", req.getProjectId(), JSONUtil.toJsonStr(response));
                throw new ServiceException(response.getMessage());
            }
            log.info("创建广告成功,项目id={}，返回参数：{}", req.getProjectId(), JSONUtil.toJsonStr(response));
            return true;
        } catch (Exception e) {
            log.info("创建广告失败,{}", e.getMessage());
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    public boolean updatePromotion(String accountId, UpdatePromotionV3Request req) {
        String accessToken = this.getAccessToken(accountId + "");

        ApiClient apiClient = new ApiClient();
        apiClient.addDefaultHeader("Access-Token", accessToken);

        PromotionUpdateV30Api api = new PromotionUpdateV30Api();
        api.setApiClient(apiClient);

        PromotionUpdateV30Request request = new PromotionUpdateV30Request();

        BeanUtil.copyProperties(req, request);
        try {
            PromotionUpdateV30Response response = api.openApiV30PromotionUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("修改广告失败," + e.getMessage());
        }
    }

    @Override
    public PromotionListV30ResponseData getPromotionList(GetPromotionListV3Request req) {
        try {
            String accessToken = this.getAccessToken(req.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            PromotionListV30Api api = new PromotionListV30Api();
            api.setApiClient(apiClient);

            PromotionListV30Filtering filtering = new PromotionListV30Filtering();
            filtering.setIds(req.getIds());
            filtering.setStatusFirst(req.getStatusFirst());
            filtering.setStatusSecond(req.getStatusSecond());

            PromotionListV30Response response = api.openApiV30PromotionListGet(req.getAdvertiserId(), filtering, null, null, req.getPageNum(), req.getPageSize(), null, null);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("获取广告列表失败," + e.getMessage());
        }
    }

    @Override
    public Boolean updatePromotiontStatus(UpdatePromotionStatusV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            PromotionStatusUpdateV30Api api = new PromotionStatusUpdateV30Api();
            api.setApiClient(apiClient);
            PromotionStatusUpdateV30Request request = new PromotionStatusUpdateV30Request();
            BeanUtil.copyProperties(qo, request);

            PromotionStatusUpdateV30Response response = api.openApiV30PromotionStatusUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("批量更新广告状态失败," + e.getMessage());
        }
    }

    @Override
    public Boolean deletePromotiont(DeletePromotionV3Request qo) {
        try {
            String accessToken = this.getAccessToken(qo.getAccountId() + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            PromotionDeleteV30Api api = new PromotionDeleteV30Api();
            api.setApiClient(apiClient);
            PromotionDeleteV30Request request = new PromotionDeleteV30Request();
            BeanUtil.copyProperties(qo, request);

            PromotionDeleteV30Response response = api.openApiV30PromotionDeletePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }

            return true;
        } catch (Exception e) {
            throw new ServiceException("批量删除广告失败," + e.getMessage());
        }
    }


    @Override
    public ToolsWechatAppletCreateV30Response createToolsWechatAppletResponse(Long accountId, CreateToolsWechatAppletReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsWechatAppletCreateV30Api api = new ToolsWechatAppletCreateV30Api();
            api.setApiClient(apiClient);

            ToolsWechatAppletCreateV30Request request = new ToolsWechatAppletCreateV30Request();
            BeanUtil.copyProperties(req, request);

            ToolsWechatAppletCreateV30Response response = api.openApiV30ToolsWechatAppletCreatePost(request);
            return response;
        } catch (Exception e) {
            throw new ServiceException("创建字节小程序失败," + e.getMessage());
        }
    }

    @Override
    public ToolsWechatAppletUpdateV30ResponseData updateToolsWechatApplet(Long accountId, UpdateToolsWechatAppletReq req) {
        try {
            String accessToken = this.getAccessToken(accountId + "");

            ApiClient apiClient = new ApiClient();
            apiClient.addDefaultHeader("Access-Token", accessToken);

            ToolsWechatAppletUpdateV30Api api = new ToolsWechatAppletUpdateV30Api();
            api.setApiClient(apiClient);

            ToolsWechatAppletUpdateV30Request request = new ToolsWechatAppletUpdateV30Request();
            BeanUtil.copyProperties(req, request);

            ToolsWechatAppletUpdateV30Response response = api.openApiV30ToolsWechatAppletUpdatePost(request);
            if (response.getCode() != 0) {
                throw new ServiceException(response.getMessage());
            }
            return response.getData();
        } catch (Exception e) {
            throw new ServiceException("更新微信小程序失败," + e.getMessage());
        }
    }


    public static String translateStatus(String status) {
        switch (status) {
            case "UNSET":
                return "未设置";
            case "IN_AUDIT":
                return "审核中";
            case "AUDIT_REJECT":
                return "审核被拒";
            case "AUDIT_PASS":
                return "审核通过";
            default:
                return "未知状态";
        }
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.format(new Date(), "HH_mm_ss_SSS"));
//        new OceanEngineRemoteServiceImpl(null, null).getCustomReport("1828809716958340", "jl_dstf", "2025-05-13", "2025-05-15", DimensionsEnum.AC);
//        OceanEngineThirdRemoteServiceImpl oceanEngineRemoteService = new OceanEngineThirdRemoteServiceImpl(null);
//        oceanEngineRemoteService.uploadImage("jl_dsbb", 1820646591563795L,new File("C:\\Users\\hhl\\Desktop\\test\\飞书20250429-163908.mp4"),"sdkfjskdf");
//        oceanEngineRemoteService.getImageList("jl_dsbb", 1820646591563795L, 1L, 100L);
//        oceanEngineRemoteService.getVideoList("jl_mytg", 1818038111548699L, 1L, 100L);
//        oceanEngineRemoteService.getVideoList("jl_mytg", 1820646591563795L, 1L, 100L);
//        oceanEngineRemoteService.getOauth2Advertiser("jl_dstf");
//        oceanEngineRemoteService.customerCenterAdvertiserList("jl_dstf",1668626934882312L,1L,100L);
    }

}
